#include <exception>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include "DbOperation.h"
#include <arpa/inet.h>
#include "../CommFormat.h"

static void show_mysql_version(mysqlpp::Connection& con)
{
	cout << "MySQL version: " << con.client_version() << endl;
}

void send2db (struct in6_addr& vr_addr6, string& buff)
{
	int type = buff[0];
	char tmp_str[40];
	int nowtime = time(NULL);

	//vr_addr6.__in6_u.__u6_addr16[0] = 0xFF05;
	//vr_addr6.__in6_u.__u6_addr16[7] = 0xb9;
	string loc_ipv6_str;
	inet_ntop(AF_INET6, (void*)&(vr_addr6), tmp_str, 40);
	loc_ipv6_str = tmp_str;

	try
	{
		if (3 == type)
		{
			int vlink_num = buff[1];
			if (0 < vlink_num)
			{
				struct VlinkStateInfo tmp_arr[vlink_num];
				int stru_len = sizeof(struct VlinkStateInfo);
				memset(&tmp_arr, 0, stru_len*vlink_num);
				try 
				{
					for (int i = 0; i < vlink_num; i++)
					{
						buff.copy((char*)(tmp_arr+i), stru_len, 2+(i*stru_len));
					}
				}
				catch (exception& e)
				{
					cout << e.what() << endl;
				}
				Connection conn("vrwebmonitor", "192.168.237.213", "xubingqing", "xubingqing");
				Query query(conn.query());
				string sql;
				string vlink_id, status, go_hops, come_hops, rrt, opp_ipv6_str, loc_ipv4_str, opp_ipv4_str, interval, ntime;
				for (int i = 0; i < vlink_num; i++)
				{
					sql.clear();
					sprintf(tmp_str, "%d", (tmp_arr+i)->vlink_no);
					vlink_id = tmp_str;
					sprintf(tmp_str, "%d", (tmp_arr+i)->status);
					status = tmp_str;
					sprintf(tmp_str, "%d", (tmp_arr+i)->req_hop_num);
					go_hops = tmp_str;
					sprintf(tmp_str, "%d", (tmp_arr+i)->res_hop_num);
					come_hops = tmp_str;
					sprintf(tmp_str, "%d", (tmp_arr+i)->rrt);
					rrt = tmp_str;
					inet_ntop(AF_INET6, (void*)&((tmp_arr+i)->peer_addr), tmp_str, 40);
					opp_ipv6_str = tmp_str;
					inet_ntop(AF_INET, (void*)&((tmp_arr+i)->local_vlink_addr), tmp_str, 40);
					loc_ipv4_str = tmp_str;
					inet_ntop(AF_INET, (void*)&((tmp_arr+i)->peer_vlink_addr), tmp_str, 40);
					opp_ipv4_str = tmp_str;
					sprintf(tmp_str, "%d", (tmp_arr+i)->hello_interval);
					interval = tmp_str;
					sprintf(tmp_str, "%d", nowtime);
					ntime = tmp_str;

					sql += "insert into vrlinkstate";
					sql += "(vraddr, locipv4, oppipv4, oppipv6, vlinkid, linkstate, gohops, comehops, rtt, sendinterval, time) values (";
					sql += "\"" + loc_ipv6_str + "\", ";
					sql += "\"" + loc_ipv4_str + "\", ";
					sql += "\"" + opp_ipv4_str + "\", ";
					sql += "\"" + opp_ipv6_str + "\", ";
					sql += "\"" + vlink_id     + "\", ";
					sql += "\"" + status       + "\", ";
					sql += "\"" + go_hops      + "\", ";
					sql += "\"" + come_hops    + "\", ";
					sql += "\"" + rrt          + "\", ";
					sql += "\"" + interval     + "\", ";
					sql += "\"" + ntime        + "\");";
					query << sql;
					query.use();
				}
				conn.disconnect();
			}
		}
		else if (4 == type)
		{
			int arr_len = buff[2];
			if (0 < arr_len)
			{
				struct VlinkIpv6Trace tmp_arr[arr_len];
				int stru_len = sizeof(struct VlinkIpv6Trace);
				memset(&tmp_arr, 0, stru_len*arr_len);
				try 
				{
					for (int i = 0; i < arr_len; i++)
					{
						buff.copy((char*)(tmp_arr+i), stru_len, 3+(i*stru_len));
					}
				}
				catch (exception& e)
				{
					cout << e.what() << endl;
				}
				Connection conn("vrwebmonitor", "192.168.237.213", "xubingqing", "xubingqing");
				Query query(conn.query());
				string sql, nod_ipv6_str, loc_ipv4_str;

				sprintf(tmp_str, "%d", buff[1]);
				string vlink_id = tmp_str;
				sql += "select locipv4 from vrlinkstate ";
				sql += "where vraddr = \"" + loc_ipv6_str + "\" and vlinkid = \"" + vlink_id + "\"";
				sql += " order by time desc limit 1;";
				cout << __LINE__ << " : " << sql;
				//query << sql;
				/*
				if (UseQueryResult res = query.use())
				{
					while (Row row = res.fetch_row())
					{
						row["locipv4"].to_string(loc_ipv4_str);
					}
					if (conn.errnum()) 
					{
						cerr << "Error received in fetching a row: " << conn.error() << endl;
					}
				}
				else
				{
					cerr << "Failed to get stock item: " << query.error() << endl;
				}
				*/
				loc_ipv4_str = "192.168.237.57";
				for (int i = 0; i < arr_len; i++)
				{
					sql.clear();
					inet_ntop(AF_INET6, (void*)&((tmp_arr+i)->addr6), tmp_str, 40);
					nod_ipv6_str = tmp_str;
					cout << nod_ipv6_str << endl;

					sql += "insert into path ";
					sql += "(vraddr, firstipv4, nodeipaddr) values (";
					sql += "'" + loc_ipv6_str + "', ";
					sql += "'" + loc_ipv4_str + "', ";
					sql += "'" + nod_ipv6_str + "');";
					cout << sql << endl;
					query << sql;
					query.use();
				}
				conn.disconnect();
			}
			//
		}
		else
		{
			cout << "in logfile: unrecognizable data came from VR.";
		}
	}
	catch (const BadQuery& er) {
		// Handle any query errors
		cerr << "Query error: " << er.what() << endl;
	}
	catch (const Exception& er) {
		// Catch-all for any other MySQL++ exceptions
		cerr << "Error: " << er.what() << endl;
	}
}

